/*
 *  ChgDoc CMS - GNU General Public License, version 3 (GPL-3.0)
 *  Copyright (C)  2012. Ian Quigley
 *  
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *  
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 */


using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.IO;
using System.Text;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;


namespace ChgDoc.Edit
{
	[AdminPage("Files", "Admin")]
    public partial class Files : System.Web.UI.Page
    {
        private string IconFolder = "<img src=\"" + Config.BaseUrl + @"edit/content/img/file/icon-folder.png"" style=""margin-right:5px;"" />";
        private string IconFolderBack = "<img src=\"" + Config.BaseUrl + @"edit/content/img/file/icon-folderback.png"" style=""margin-right:5px;""  />";
        private string IconUnknown = "<img src=\"" + Config.BaseUrl + @"edit/content/img/file/icon-unknown.png"" style=""margin-right:5px;"" />";
        private string IconImage = "<img src=\"" + Config.BaseUrl + @"edit/content/img/file/icon-image.png"" style=""margin-right:5px;"" />";
        private string IconText = "<img src=\"" + Config.BaseUrl + @"edit/content/img/file/icon-text.png"" style=""margin-right:5px;"" />";


        protected void Page_Load(object sender, EventArgs e)
        {
            if (Request.QueryString["act"] != null)
            {
                switch (Request.QueryString["act"])
                {
                    case "deldir":
                        if (Request.QueryString["dir"] == null)
                            break;

                        try
                        {
                            DirectoryInfo di = new DirectoryInfo(BrowseDirectory);
                            di.Delete(true);
                        }
                        catch
                        {}
                        string dir = ParentDir(Request.QueryString["dir"]);
                        Response.Redirect(Config.BaseUrl + "edit/files.aspx" + (dir == string.Empty ? "" : "?dir=" + dir));

                        break;

                    case "delfile":
                        if (Request.QueryString["file"] == null)
                            break;

                        
                        try
                        {
                            FileInfo fi = new FileInfo(Path.Combine(BrowseDirectory, Request.QueryString["file"]));
                            if (fi.Exists)
                                fi.Delete();
                        }
                        catch
                        {}

                        Response.Redirect(Config.BaseUrl +  "edit/files.aspx" + (Request.QueryString["dir"] == "" ? "" : "?dir=" + Request.QueryString["dir"]));
                        break;

                    default:
                        break;
                }
            }

            UpdateListing(BrowseDirectory);
        }

        private string BrowseDirectory
        {
            get
            {
                string directory = Config.UploadFolder;
                try
                {
                    if (Request.QueryString["dir"] != null)
                        directory = Path.Combine(directory, HttpUtility.UrlDecode(Request.QueryString["dir"]));
                }
                catch
                {}

                DirectoryInfo di = new DirectoryInfo(directory);
                if ((di.Exists == false) || (di.FullName.IndexOf(Config.UploadFolder) != 0))
                    directory = Config.UploadFolder;

                return directory;
            }
        }

        public bool BrowseDirectoryIsRoot
        {
            get
            {
                return (Request.QueryString["dir"] == null);
            }
        }

        public void UpdateListing(string directory)
        {
            litListing.Text = string.Empty;

            string uploadDir = Config.UploadFolder;
            if (directory.IndexOf(uploadDir) != 0)
            {
                divFilePage.Visible = false;
                ((Admin)Master).SetMessage( Admin.MessageLevel.Error, "Invalid request." );
                return;
            }

            uploadDir = directory.Substring(uploadDir.Length);
            litDirectory.Text = uploadDir.Length != 0 ? uploadDir : "Root";
            
            if (Directory.Exists(directory) == false)
            {
                divFilePage.Visible = false;
                ((Admin)Master).SetMessage( Admin.MessageLevel.Error, "Missing directory." );
                return;
            }

            string[] files = Directory.GetFiles(directory);
            string[] directories = Directory.GetDirectories(directory);


            StringBuilder html = new StringBuilder();

            

            if (BrowseDirectoryIsRoot == false)
            {
                string dir = HttpUtility.UrlDecode(Request.QueryString["dir"]);
                html.AppendFormat("<tr><td valign=\"center\" align=\"right\">" + IconFolderBack + "</td><td valign=center colspan=2><a href=\"files.aspx{0}\">Parent directory</a></td></tr>", (dir.IndexOf("/") == -1 ? "" : "?dir=" + HttpUtility.UrlEncode(ParentDir(dir))));
            }

            if (directories.Length > 0) 
            {
                foreach (string dir in directories)
                {
                    html.AppendFormat("<tr><td valign=\"center\" align=\"right\">{2}</td><td valign=center><a href=\"files.aspx?dir={0}\">{1}</a></td><td valign=center class=danger><a href=\"files.aspx?dir={0}&act=deldir\">delete</td></tr>", HttpUtility.UrlEncode(RelativeDirectory(dir)), HttpUtility.HtmlEncode(DirectoryName(dir)), IconFolder);
                }
            }

            if (files.Length > 0)
            {
                string dirpart;
                if (BrowseDirectoryIsRoot)
                    dirpart = string.Empty;
                else
                    dirpart = "&dir=" + Request.QueryString["dir"];

                foreach (string filename  in files)
                {
                    string actionOpen = string.Empty;
                    string actionClose = string.Empty;
                    string actionIcon = IconUnknown;

                    switch (Path.GetExtension(filename).ToLower())
                    {
                        case ".png":
                        case ".jpg":
                        case ".gif":
                    		string folder = Config.UploadFolderUrl;
							if (Request.QueryString["dir"] != null)
								folder += Request.QueryString["dir"];

                            if (folder[folder.Length - 1] != '/')
                                folder += '/';

                            actionOpen = "<a href=\"" + folder +  Path.GetFileName(filename) + "\">";
                            actionClose = "</a>";
                            actionIcon = IconImage;
                            break;

                        case ".css":
                            actionOpen = "<a href=\"filetextedit.aspx?mode=css&file=" + Path.GetFileName(filename) + dirpart + "\">";
                            actionClose = "</a>";
                            actionIcon = IconText;
                            break;
                        case ".js":
                            actionOpen = "<a href=\"filetextedit.aspx?mode=js&file=" + Path.GetFileName(filename) + dirpart + "\">";
                            actionClose = "</a>";
                            actionIcon = IconText;
                            break;

                        case ".txt":
                        case ".html":
                        case ".htm":
                        case ".xml":
                            actionOpen = "<a href=\"filetextedit.aspx?file=" + Path.GetFileName(filename) + dirpart + "\">";
                            actionClose = "</a>";
                            actionIcon = IconText;
                            break;

                    }
                    html.AppendFormat("<tr><td valign=\"center\" align=\"right\">{2}</td><td valign=center>{3}{0}{4}</td><td valign=center><a href=\"files.aspx?file={0}&act=delfile{1}\">delete</a></td></tr>", Path.GetFileName(filename), dirpart, actionIcon, actionOpen, actionClose);
                }
                
            }
            if (files.Length + directories.Length == 0)
            {
                html.Append("<tr><td>&nbsp;</td><td colspan=2><span class=\"boring\">Empty</span></td></tr>");
            }

            litListing.Text = html.ToString();
        }

        private string ParentDir(string dir)
        {
            if (dir.IndexOf("\\") == -1)
                return string.Empty;

            return dir.Substring(0, dir.LastIndexOf("\\"));
        }

        private string DirectoryName(string dir)
        {
            if (dir.IndexOf("\\") == -1)
                return dir;
                        
            return dir.Substring(dir.LastIndexOf("\\") + 1);
        }

        private string RelativeDirectory(string directory)
        {
            string relative = Path.Combine(BrowseDirectory, directory);
            relative = relative.Substring(Config.UploadFolder.Length + 1);
            return relative;
        }

        protected void btnNewFolder_Click(object sender, EventArgs e)
        {
            DirectoryInfo dirInfo = new DirectoryInfo(BrowseDirectory);
            if (dirInfo.Exists == false)
                return;

            dirInfo.CreateSubdirectory(txtFolder.Text);
            txtFolder.Text = "";

            UpdateListing(BrowseDirectory);            
        }

        protected void btnUploadFile_click(object sender, EventArgs e)
        {
            try
            {
                string newFilePath = Path.Combine(BrowseDirectory, Path.GetFileName(uploadFile.PostedFile.FileName));
                if (File.Exists(newFilePath))
                    File.Delete(newFilePath);

                uploadFile.PostedFile.SaveAs(newFilePath);

            }
            catch 
            {
            }

            Response.Redirect(Config.BaseUrl + "edit/files.aspx" + (Request.QueryString["dir"] == "" ? "" : "?dir=" + Request.QueryString["dir"]));
        }
    }
}
